package com.xdf.whiteaccount.config;

import com.xdf.whiteaccount.cache.EhCacheManager;
import com.xdf.whiteaccount.config.properties.ShiroConfigParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @program: xzy-management-system
 * @description: shiro配置
 * @author: 张柯
 * @create: 2020-12-31 14:53
 **/
@Slf4j
@Configuration
@EnableConfigurationProperties(ShiroConfigParam.class)
@Order(4)
public class ShiroConfig {
    private ShiroConfigParam param;

    @Autowired
    public void setParam(ShiroConfigParam param) {
        this.param = param;
    }

    /**
     * 自定义Reaml
     *
     * @return
     */
    @Bean("userRealm")
    public ShiroRealm getRealm() {
        return new ShiroRealm();
    }

    /**
     * @return
     */
    /*@Bean("lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }*/

    @Bean("defaultAdvisorAutoProxyCreator")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        defaultAdvisorAutoProxyCreator.setUsePrefix(false);
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor a = new AuthorizationAttributeSourceAdvisor();
        a.setSecurityManager(securityManager);
        return a;
    }

    /**
     * shiro过滤器
     *
     * @param securityManager
     * @return
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(
//            @Qualifier("jwtFilter") JWTFilter jwtFilter,
            @Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //  自定义过滤方法
//        Map<String, Filter> filterMap = new HashMap<>();
//        filterMap.put("jwt", jwtFilter);
//        shiroFilterFactoryBean.setFilters(filterMap);
        //  增加过滤链
        String[] urls = param.getAnonymousUrls().split(",");
        Map<String, String> filterChainMap = new LinkedHashMap<>();
        for (String url : urls) {
            filterChainMap.put(url, "anon");
        }
        filterChainMap.put("/swagger-ui.html/**", "anon");
        filterChainMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setSuccessUrl("/");
        shiroFilterFactoryBean.setUnauthorizedUrl("unauthorized");
        return shiroFilterFactoryBean;
    }

    /**
     * 权限管理器
     *
     * @return
     */
    @Bean("securityManager")
    public SecurityManager securityManager(
            @Qualifier("shiroCacheManager") CacheManager cacheManager,
            @Qualifier("userRealm") ShiroRealm shiroRealm,
            @Qualifier("rememberMeManager") RememberMeManager rememberMeManager,
            @Qualifier("sessionManager") SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm);
        securityManager.setSessionManager(sessionManager);
        securityManager.setCacheManager(cacheManager);
//        securityManager.setRememberMeManager(rememberMeManager);
        return securityManager;
    }

    /*@Bean("subjectDAO")
    public DefaultSubjectDAO subjectDAO(@Qualifier("defaultSessionStorageEvaluator") DefaultSessionStorageEvaluator sessionStorageEvaluator) {
        DefaultSubjectDAO defaultSubjectDAO = new DefaultSubjectDAO();
        defaultSubjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator);
        return defaultSubjectDAO;
    }

    @Bean("statelessDefaultSubjectFactory")
    public StatelessDefaultSubjectFactory statelessDefaultSubjectFactory() {
        StatelessDefaultSubjectFactory statelessDefaultSubjectFactory = new StatelessDefaultSubjectFactory();
        return statelessDefaultSubjectFactory;
    }

    @Bean(name = "defaultSessionStorageEvaluator")
    public DefaultSessionStorageEvaluator defaultSessionStorageEvaluator() {
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        return defaultSessionStorageEvaluator;
    }

    @Bean("subjectFactory")
    public SubjectFactory subjectFactory() {
        return new StatelessDefaultSubjectFactory();
    }*/

    /**
     * Session管理器
     *
     * @return
     */
    @Bean("sessionManager")
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setGlobalSessionTimeout(param.getExpireTime());
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setSessionIdCookieEnabled(true);
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setDeleteInvalidSessions(true);
        return sessionManager;
    }

    /**
     * 缓存管理器
     *
     * @return
     */
    @Bean("shiroCacheManager")
    public CacheManager cacheManager() {
        return new EhCacheManager();
    }

    /**
     * RememberMe管理器
     *
     * @param cookie
     * @return
     */
    @Bean("rememberMeManager")
    public CookieRememberMeManager rememberMeManager(@Qualifier("simpleCookie") SimpleCookie cookie) {
        CookieRememberMeManager manager = new CookieRememberMeManager();
        manager.setCookie(cookie);
        return manager;
    }

    /**
     * Cookie
     *
     * @return
     */
    @Bean("simpleCookie")
    public SimpleCookie simpleCookie() {
        SimpleCookie cookie = new SimpleCookie();
        cookie.setMaxAge(604800);
        cookie.setHttpOnly(true);
        return cookie;
    }

    /**
     * JWTFilter
     *
     * @return
     */
    /*@Bean("jwtFilter")
    public JWTFilter jwtFilter() {
        return new JWTFilter();
    }*/

}
